package com.itheima.service;

import com.alibaba.dubbo.config.annotation.Service;
import com.itheima.dao.MemberDao;
import com.itheima.dao.OrderDao;
import com.itheima.dao.SetmealDao;
import com.itheima.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * 统计报表服务
 */
@Service(interfaceClass = ReportService.class)
@Transactional
public class ReportServiceImpl implements ReportService {

    @Autowired
    private MemberDao memberDao;

    @Autowired
    private OrderDao orderDao;

    @Autowired
    private SetmealDao setmealDao;

    /**
     * 获得运营统计数据
     * Map数据格式：
     * todayNewMember ‐> number
     * totalMember ‐> number
     * thisWeekNewMember ‐> number
     * thisMonthNewMember ‐> number
     * todayOrderNumber ‐> number
     * todayVisitsNumber ‐> number
     * thisWeekOrderNumber ‐> number
     * thisWeekVisitsNumber ‐> number
     * thisMonthOrderNumber ‐> number
     * thisMonthVisitsNumber ‐> number
     * hotSetmeal ‐> List<Setmeal>
     */
    public Map<String, Object> getBusinessReport() throws Exception {

        //获得当前日期
        String today = DateUtils.parseDate2String(DateUtils.getToday());
        //获得本周一的日期
        String thisWeekMonday = DateUtils.parseDate2String(DateUtils.getThisWeekMonday());
        //获得本月第一天的日期
        String firstDay4ThisMonth = DateUtils.parseDate2String(DateUtils.getFirstDay4ThisMonth());

        //今日新增会员数
        Integer todayNewMember = memberDao.findMemberCountByDate(today);
        //总会员数
        Integer totalMember = memberDao.findMemberTotalCount();
        //本周新增会员数
        Integer thisWeekNewMember = memberDao.findMemberCountAfterDate(thisWeekMonday);
        //本月新增会员数
        Integer thisMonthNewMember = memberDao.findMemberCountAfterDate(firstDay4ThisMonth);

        //今日预约数
        Integer todayOrderNumber = orderDao.findOrderCountByDate(today);
        //本周预约数
        Integer thisWeekOrderNumber = orderDao.findOrderCountAfterDate(thisWeekMonday);
        //本月预约数
        Integer thisMonthOrderNumber = orderDao.findOrderCountAfterDate(firstDay4ThisMonth);
        //今日到诊数
        Integer todayVisitsNumber = orderDao.findVisitsCountByDate(today);
        //本周到诊数
        Integer thisWeekVisitsNumber = orderDao.findVisitsCountAfterDate(thisWeekMonday);
        //本月到诊数
        Integer thisMonthVisitsNumber = orderDao.findVisitsCountAfterDate(firstDay4ThisMonth);

        //热门套餐（取前4）
        List<Map> hotSetmeal = orderDao.findHotSetmeal();

        Map<String, Object> result = new HashMap<>();
        result.put("reportDate", today);
        result.put("todayNewMember", todayNewMember);
        result.put("totalMember", totalMember);
        result.put("thisWeekNewMember", thisWeekNewMember);
        result.put("thisMonthNewMember", thisMonthNewMember);
        result.put("todayOrderNumber", todayOrderNumber);
        result.put("thisWeekOrderNumber", thisWeekOrderNumber);
        result.put("thisMonthOrderNumber", thisMonthOrderNumber);
        result.put("todayVisitsNumber", todayVisitsNumber);
        result.put("thisWeekVisitsNumber", thisWeekVisitsNumber);
        result.put("thisMonthVisitsNumber", thisMonthVisitsNumber);
        result.put("hotSetmeal", hotSetmeal);
        return result;
    }

    //获取指定时间段每日预约.到诊数量
    public Map<String, Object> getEverdayCount(List<String> dateList) {
        Map<String, Object> map = new HashMap<>();
        map.put("dateList", dateList);
        List<Integer> orderList = new ArrayList<>();
        List<Integer> visitsList = new ArrayList<>();
        //遍历日期列表,获取每日预约次数和到诊次数并加到相应的集合中
        for (String s : dateList) {
            Integer orderCount = orderDao.findOrderCountByDate(s);
            orderList.add(orderCount);
            Integer VisitsCount = orderDao.findVisitsCountByDate(s);
            visitsList.add(VisitsCount);
        }
        map.put("orderCount", orderList);
        map.put("visitsCount", visitsList);
        return map;
    }


    //获取指定时间段内各套餐收入以及总收入
    public Map<String, Object> getSetmealIncome(String start, String end) {
        Map date = new HashMap<>();
        date.put("start", start);
        date.put("end", end);
        //获取的List集合中 每个map集合包含两队数据   分别是 key="name"  值为套餐名    和  key="value"   值为套餐被预约次数
        List<Map<String, Object>> setmealCountByDate = setmealDao.getSetmealCountByDate(date);
        //获取的List集合中 每个map集合包含两队数据   分别是 key="name"  值为套餐名    和  key="value"   值为套餐价格
        List<Map<String, Object>> setmealPrice = setmealDao.findSetmealPrice();
        //套餐名集合
        List<String> setmealNames = new ArrayList<>();
        //各个套餐收入以及总收入集合
        List<Integer> setmealIncome = new ArrayList<>();
        //获得以  套餐名为Key  套餐被预约次数为值的集合
        List<Map<String, Object>> mc = new ArrayList<>();
        for (Map<String, Object> cMap : setmealCountByDate) {
            Map<String, Object> ct = new HashMap<>();
            String name = (String) cMap.get("name");
            Object value = cMap.get("value");
            if (value == null) {
                value = 0;
            }
            ct.put(name, value);
            mc.add(ct);
        }
        //获得以  套餐名为Key  套餐价格为值的集合
        List<Map<String, Object>> mp = new ArrayList<>();
        for (Map<String, Object> pMap : setmealPrice) {
            Map<String, Object> cp = new HashMap<>();
            String name = (String) pMap.get("name");
            Object value = pMap.get("value");
            cp.put(name, value);
            mp.add(cp);
        }
        for (Map<String, Object> countMap : mc) {
            //获取套餐计数Map集合的key集合
            Set<String> ckey = countMap.keySet();
            //遍历集合获取key
            for (String x : ckey) {
                //将套餐名加入到list集合中
                setmealNames.add(x);
                for (Map<String, Object> priceMap : mp) {
                    //获取套餐价格Map集合的key集合
                    Set<String> skey = priceMap.keySet();
                    //遍历集合获取key
                    for (String y : skey) {
                        //比较两个key的值是否相同,相同则获取对应的计数和价格
                        if (x.equals(y)) {
                            long co = (long) countMap.get(x);
                            int count = (int) co;
                            float price = (float) priceMap.get(y);
                            //将套餐总价算出并加入到list集合中
                            setmealIncome.add((int) (count * price));
                            continue;
                        }
                    }
                }
            }
        }
        //在套餐名集合中加入  总收入
        setmealNames.add("总收入");
        Integer generalIncome = 0;
        //计算出总收入,并加入到收入集合中
        for (Integer o : setmealIncome) {
            generalIncome += o;
        }
        setmealIncome.add(generalIncome);
        //将套餐名列表和收入列表加入到 map集合中,并返回给前端控制器
        Map<String, Object> map = new HashMap<>();
        map.put("setmealNames", setmealNames);
        map.put("incomeList", setmealIncome);
        return map;
    }
}